package wuziqi;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.*;
import java.util.List;

public class GamePanle extends JPanel  implements ActionListener, MouseListener, MouseMotionListener {
    //右边的三个下拉框
    private JComboBox<String> 下拉框_fightType, 下拉框_playFirst, 下拉框_chessColor;

    //右边的三个个按钮
    private JButton btn_new, btn_undo, btn_surrender;

    //右边的四个内容会发生变化的文本标签
    private JLabel txt_blackUndo, txt_blackState, txt_whiteUndo, txt_whiteState;

    //白棋的悔棋次数
    int whiteUndoNum = 3;

    //黑棋的悔棋次数
    int blackUndoNum = 3;


    List<Step> 棋谱 = new ArrayList<Step>();
    List<Step> 白谱 = new ArrayList<Step>();
    List<Step> 黑谱 = new ArrayList<Step>();
    List<Step> 胜谱 = new ArrayList<Step>();


    //落子指示器
    Step stepPointer = new Step();


    /**
     * 对战方式（0-人机对战，1-人人对战）
     */
    int fightType;

    /**
     * 先手选择（0-玩家先手，1-电脑先手）
     */
    int playFirst;

    /**
     * 黑白选择（0-玩家执黑，1-玩家执白）
     */
    int chessColor;

    /**
     * 判断游戏是否结束（true-结束，false-未结束）
     */
    boolean isGameOver = true;

    int 电脑棋子颜色;
    int 玩家棋子颜色;


    public GamePanle() {

        this.setSize(Const.窗口宽度, Const.窗口高度);
        this.setBackground(new Color(90, 210, 88));


        //画右边的操作区域
        this.option();

        this.initGame();

    }

    void option() {
        this.setLayout(null);

        Font font = new Font("微软雅黑", Font.BOLD, 12);

        //=================对战方式===================
        JLabel txt1 = new JLabel("对战方式：");
        txt1.setFont(font);
        txt1.setForeground(Color.WHITE);
        txt1.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y, 100, 24);
        this.add(txt1);

        this.下拉框_fightType = new JComboBox<String>(new String[]{"人机对战", "人人对战"});
        this.下拉框_fightType.setFont(font);
        this.下拉框_fightType.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 30, 100, 24);
        this.add(this.下拉框_fightType);
        //=========================================

        //谁先手===============================================
        JLabel txt2 = new JLabel("先手选择：");
        txt2.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 70, 100, 24);
        txt2.setFont(font);
        txt2.setForeground(Color.WHITE);
        this.add(txt2);

        this.下拉框_playFirst = new JComboBox<String>(new String[]{"玩家先手", "电脑先手"});
        this.下拉框_playFirst.setFont(font);
        this.下拉框_playFirst.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 100, 100, 24);
        this.add(this.下拉框_playFirst);
        //===================================================

        //谁执黑===============================================
        JLabel txt3 = new JLabel("黑白选择：");
        txt3.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 140, 100, 24);
        txt3.setFont(font);
        txt3.setForeground(Color.WHITE);
        this.add(txt3);

        this.下拉框_chessColor = new JComboBox<String>(new String[]{"玩家执黑", "玩家执白"});
        this.下拉框_chessColor.setFont(font);
        this.下拉框_chessColor.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 170, 100, 24);
        this.add(this.下拉框_chessColor);
        //===================================================

        //开始游戏按钮
        this.btn_new = new JButton("开始游戏");
        this.btn_new.setFont(font);
        this.btn_new.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 230, 100, 30);
        this.add(this.btn_new);

        //悔棋按钮
        this.btn_undo = new JButton("我要悔棋");
        this.btn_undo.setFont(font);
        this.btn_undo.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 280, 100, 30);
        this.btn_undo.setEnabled(false);
        this.add(this.btn_undo);

        //认输按钮
        this.btn_surrender = new JButton("我认输了");
        this.btn_surrender.setFont(font);
        this.btn_surrender.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 330, 100, 30);
        this.btn_surrender.setEnabled(false);
        this.add(this.btn_surrender);

        // 黑棋提示组框===========================================
        JPanel groupBoxBlack = new JPanel();
        groupBoxBlack.setLayout(null);
        groupBoxBlack.setBackground(this.getBackground());
        groupBoxBlack.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 380, 100, 80);
        groupBoxBlack.setBorder(BorderFactory.createTitledBorder("黑棋"));
        this.add(groupBoxBlack);

        JLabel txt4 = new JLabel("悔棋：");
        txt4.setFont(font);
        txt4.setForeground(Color.WHITE);
        txt4.setBounds(10, 16, 40, 30);
        groupBoxBlack.add(txt4);

        this.txt_blackUndo = new JLabel("剩 " + this.blackUndoNum + " 次");
        this.txt_blackUndo.setFont(font);
        this.txt_blackUndo.setForeground(Color.darkGray);
        this.txt_blackUndo.setBounds(44, 16, 50, 30);
        groupBoxBlack.add(this.txt_blackUndo);

        JLabel txt5 = new JLabel("状态：");
        txt5.setFont(font);
        txt5.setForeground(Color.WHITE);
        txt5.setBounds(10, 44, 40, 30);
        groupBoxBlack.add(txt5);

        this.txt_blackState = new JLabel("未开始");
        this.txt_blackState.setFont(font);
        this.txt_blackState.setForeground(Color.darkGray);
        this.txt_blackState.setBounds(44, 44, 50, 30);
        groupBoxBlack.add(this.txt_blackState);
        //===============================================

        //白棋提示组框 ===========================================
        JPanel groupBoxWhite = new JPanel();
        groupBoxWhite.setLayout(null);
        groupBoxWhite.setBackground(this.getBackground());
        groupBoxWhite.setBounds(Const.左上角坐标X + Const.棋盘宽度 + 30, Const.左上角坐标Y + 480, 100, 80);
        groupBoxWhite.setBorder(BorderFactory.createTitledBorder("白棋"));
        this.add(groupBoxWhite);

        JLabel txt6 = new JLabel("悔棋：");
        txt6.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        txt6.setForeground(Color.WHITE);
        txt6.setBounds(10, 16, 40, 30);
        groupBoxWhite.add(txt6);

        this.txt_whiteUndo = new JLabel("剩 " + this.whiteUndoNum + " 次");
        this.txt_whiteUndo.setFont(font);
        this.txt_whiteUndo.setForeground(Color.darkGray);
        this.txt_whiteUndo.setBounds(44, 16, 50, 30);
        groupBoxWhite.add(this.txt_whiteUndo);

        JLabel txt7 = new JLabel("状态：");
        txt7.setFont(font);
        txt7.setForeground(Color.WHITE);
        txt7.setBounds(10, 44, 40, 30);
        groupBoxWhite.add(txt7);

        this.txt_whiteState = new JLabel("未开始");
        this.txt_whiteState.setFont(font);
        this.txt_whiteState.setForeground(Color.darkGray);
        this.txt_whiteState.setBounds(44, 44, 50, 30);
        groupBoxWhite.add(this.txt_whiteState);
        //===================================================

        //后面,要给这些按钮加点击事件 ...
        btn_new.setActionCommand("new");
        btn_new.addActionListener(this);

        btn_undo.setActionCommand("undo");
        btn_undo.addActionListener(this);

        btn_surrender.setActionCommand("surrender");
        btn_surrender.addActionListener(this);

        //
        this.addMouseListener(this);
        this.addMouseMotionListener(this);


    }

    @Override
    public void actionPerformed(ActionEvent e) {

        String command = e.getActionCommand();

        if (command == "new") {
            JOptionPane.showMessageDialog(this, "开始游戏");
            this.newGame();
        } else if (command == "undo") {
            JOptionPane.showMessageDialog(this, "悔棋");
        } else if (command == "surrender") {
            int r = JOptionPane.showConfirmDialog(this, "确定要认输吗", "提示", JOptionPane.OK_CANCEL_OPTION);
            System.out.println(r); //确定为0, 取消为 2
        } else if (command == "exit") {
            System.exit(0);
        } else if (command == "about") {
            JOptionPane.showMessageDialog(this, "关于...");
        }

    }

//    编写 setComponentState() 函数
//    这个函数的意思,就是根据游戏是不是已经开始了,控制各个按钮和下拉框的状态

    public void setComponentState(boolean isBegin) {
        if (isBegin) // 新游戏已经开始了
        {
            this.下拉框_fightType.setEnabled(false);
            this.下拉框_playFirst.setEnabled(false);
            this.下拉框_chessColor.setEnabled(false);
            this.btn_new.setEnabled(false);
            this.btn_undo.setEnabled(true);
            this.btn_surrender.setEnabled(true);
        } else // 新游戏还未开始
        {
            this.下拉框_fightType.setEnabled(true);
            this.下拉框_playFirst.setEnabled(true);
            this.下拉框_chessColor.setEnabled(true);
            this.btn_new.setEnabled(true);
            this.btn_undo.setEnabled(false);
            this.btn_surrender.setEnabled(false);
        }
    }

    //初始化函数
    void initGame() {
        this.isGameOver = true;
        // 清空下棋列表
        this.棋谱.clear();
        this.黑谱.clear();
        this.白谱.clear();
        this.胜谱.clear();

        // 落子指示器初始化
        this.stepPointer.x = -1;
        this.stepPointer.y = -1;
        this.stepPointer.show = 0; // 0-不显示，1-显示

        // 对战方式
        if ("人人对战".equals(this.下拉框_fightType.getSelectedItem().toString())) {
            this.fightType = 1;
        } else {
            this.fightType = 0;
        }
        // 先手选择
        if ("电脑先手".equals(this.下拉框_playFirst.getSelectedItem().toString())) {
            this.playFirst = 1;
        } else {
            this.playFirst = 0;
        }
        // 黑白选择
        if ("玩家执白".equals(this.下拉框_chessColor.getSelectedItem().toString())) {
            this.chessColor = 1;
        } else {
            this.chessColor = 0;
        }

        // 电脑与玩家棋子颜色
        if (this.fightType == 0) {
            if (this.chessColor == 1) {
                this.电脑棋子颜色 = Const.黑棋标识_1;
                this.玩家棋子颜色 = Const.白棋标识_2;

            } else {
                this.玩家棋子颜色 = Const.黑棋标识_1;
                this.电脑棋子颜色 = Const.白棋标识_2;
            }
        }

        // 悔棋数初始化
        this.whiteUndoNum = 3;
        this.blackUndoNum = 3;

        setComponentState(false);
    }

    public void newGame() {
        //初始化游戏
        this.initGame();

        //设置控制制区状态
        setComponentState(true);

        this.isGameOver = false;

        //fightType==0表示选的是人机对战, playFirst==1 表示电脑先行
        if (this.fightType == 0 && this.playFirst == 1) {
            //电脑走棋,以后完成
        }
    }

    public void paint(Graphics g) {
        super.paint(g);

//        //往棋谱中添加一些模拟数据
//        this.棋谱.add(new Step(6,6,Const.白棋标识_2));
//
//        this.棋谱.add(new Step(10,9,Const.白棋标识_2));


        画棋盘(g);

        画棋子(g);

        //落子指示器
//        this.stepPointer.x=9;
//        this.stepPointer.y=9;
//        this.stepPointer.show=1;

        画落子指示器(g);

//        this.胜谱.add(new Step(8, 7, Const.白棋标识_2));
//        this.胜谱.add(new Step(9, 8, Const.白棋标识_2));
//        this.胜谱.add(new Step(10, 9, Const.白棋标识_2));
//        this.胜谱.add(new Step(11, 10, Const.白棋标识_2));
//        this.胜谱.add(new Step(12, 11, Const.白棋标识_2));

        画五子成线(g);
    }


    void 画棋盘(Graphics g) {

        g.setColor(Color.BLACK);

        for (int i = 0; i < Const.横格数; i++) {
            g.drawLine(Const.左上角坐标X, Const.左上角坐标Y + i * Const.格子宽度, Const.左上角坐标X + Const.棋盘宽度,
                    Const.左上角坐标Y + i * Const.格子宽度);

            g.drawLine(Const.左上角坐标X + i * Const.格子宽度, Const.左上角坐标Y, Const.左上角坐标X + i * Const.格子宽度,
                    Const.左上角坐标Y + Const.棋盘高度);
        }

        // 画5个定位点
        // g.fillArc(x,y, d, d,180,180)
        // x坐标 y坐标 长 宽 开始弧度 结束弧度
        g.fillArc(Const.左上角坐标X + 3 * Const.格子宽度 - 4, Const.左上角坐标Y + 3 * Const.格子宽度 - 4, 8, 8, 0, 360);
        g.fillArc(Const.左上角坐标X + 15 * Const.格子宽度 - 4, Const.左上角坐标Y + 3 * Const.格子宽度 - 4, 8, 8, 0, 360);
        g.fillArc(Const.左上角坐标X + 9 * Const.格子宽度 - 4, Const.左上角坐标Y + 9 * Const.格子宽度 - 4, 8, 8, 0, 360);
        g.fillArc(Const.左上角坐标X + 3 * Const.格子宽度 - 4, Const.左上角坐标Y + 15 * Const.格子宽度 - 4, 8, 8, 0, 360);
        g.fillArc(Const.左上角坐标X + 15 * Const.格子宽度 - 4, Const.左上角坐标Y + 15 * Const.格子宽度 - 4, 8, 8, 0, 360);


    }

    //画棋子
    void 画棋子(Graphics g) {
        for (Step step : 棋谱) {
            // 将垂直与水平线的数目转化为像素
            int pX = Const.左上角坐标X + step.x * Const.格子宽度;
            int pY = Const.左上角坐标Y + step.y * Const.格子宽度;

            Graphics2D g2D = (Graphics2D) g;

            int color = step.黑白标志 == Const.白棋标识_2 ? 90 : 10;

            RadialGradientPaint paint
                    = new RadialGradientPaint(pX, pY, color, new float[]{0f, 1f}, new Color[]{Color.WHITE, Color.BLACK});
            g2D.setPaint(paint);

            // 着色微调
            g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 消除画图锯齿

            Ellipse2D e = new Ellipse2D.Float(pX - Const.棋子直径 / 2, pY - Const.棋子直径 / 2, Const.棋子直径, Const.棋子直径);
            g2D.fill(e);
        }
    }

    void 画落子指示器(Graphics g) {
        if (this.stepPointer.show == 1) {
            Graphics2D g2D = (Graphics2D) g;
            g2D.setColor(Color.RED);
            g2D.setStroke(new BasicStroke(2.5f));

            // 先以交叉点为中心取到指示器周围的4个角坐标
            // 中心点坐标
            int x = Const.左上角坐标X + stepPointer.x * Const.格子宽度;
            int y = Const.左上角坐标Y + stepPointer.y * Const.格子宽度;

            // 左上角坐标，并向下向右画线
            int x1 = x - Const.棋子直径 / 2;
            int y1 = y - Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 + Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 + Const.棋子直径 / 4, y1);

            // 右上角坐标，并向下向左画线
            x1 = x + Const.棋子直径 / 2;
            y1 = y - Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 + Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 - Const.棋子直径 / 4, y1);

            // 左下角坐标，并向上向右画线
            x1 = x - Const.棋子直径 / 2;
            y1 = y + Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 - Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 + Const.棋子直径 / 4, y1);

            // 右下角坐标，并向上向左画线
            x1 = x + Const.棋子直径 / 2;
            y1 = y + Const.棋子直径 / 2;
            g2D.drawLine(x1, y1, x1, y1 - Const.棋子直径 / 4);
            g2D.drawLine(x1, y1, x1 - Const.棋子直径 / 4, y1);
        }
    }

    void 画五子成线(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        if (this.胜谱.size() == 5) {
            g2D.setColor(Color.RED);
            g2D.setStroke(new BasicStroke(2.5f));
            int x1 = 胜谱.get(0).x;
            int y1 = 胜谱.get(0).y;

            //	g2D.drawLine(Const.左上角坐标X + x1 * Const.格子宽度, Const.左上角坐标Y + y1 * Const.格子宽度,
            //			Const.左上角坐标X + 胜谱.get(4).x * Const.格子宽度, Const.左上角坐标Y + 胜谱.get(4).y * Const.格子宽度);

            for (int i = 0; i < this.胜谱.size(); i++) {
                Step step = this.胜谱.get(i);
                if (i == 0) { // 先得到第一个点
                    x1 = step.x;
                    y1 = step.y;
                } else { // 再用第一个点与其他的点连线
                    g2D.drawLine(Const.左上角坐标X + x1 * Const.格子宽度, Const.左上角坐标Y + y1 * Const.格子宽度,
                            Const.左上角坐标X + step.x * Const.格子宽度, Const.左上角坐标Y + step.y * Const.格子宽度);
                }
            }
        }
    }


    public void mouseClicked(MouseEvent e) {
        if (this.isGameOver) {
            return;
        }

        if (e.getButton() == MouseEvent.BUTTON1) { // 鼠标左键点击
            int x = e.getX();
            int y = e.getY();

            // 将x,y由像素改为相应的水平与垂直线的数目（0~19）
            int lineX = (x - Const.左上角坐标X + Const.格子宽度 / 2) / Const.格子宽度;
            int lineY = (y - Const.左上角坐标Y + Const.格子宽度 / 2) / Const.格子宽度;

            // 判断该位置是否有棋子
            boolean hasChess = false;
            for (int i = 0; i < this.棋谱.size(); i++) {
                Step step = this.棋谱.get(i);
                if (step.x == lineX && step.y == lineY) {
                    hasChess = true;
                    break;
                }
            }

            //如果这个位置上没有棋子,表示玩家可以下棋了
            if (hasChess == false) {
                // 清除落子指示器
                this.stepPointer.show = 0;

                //得到这步棋子的颜色
                int stepColor = getNextStepColor();

                //记录这步棋
                Step stepMan = new Step(lineX, lineY, stepColor);

                this.棋谱.add(stepMan);

            }
            this.repaint();

            // 要进行胜负判判断
            if (this.胜负判断() == true) {
                this.isGameOver = true;
                this.setComponentState(false);
                this.txt_blackState.setText("已结束");
                this.txt_whiteState.setText("已结束");
                return;
            }

            // 判断双方是否战平（棋盘下满了）
            if (this.棋谱.size() >= 361) {
                JOptionPane.showMessageDialog(null, "棋盘没地方下了,平局");
                this.isGameOver = true;
                this.initGame();
                return;
            }

            // 人机对战
            //如果是人机对战
            if(this.fightType==0) {
                Computer AI=new Computer(this);
                AI.play();

                if (this.电脑棋子颜色 == Const.黑棋标识_1) {
                    this.txt_blackState.setText("已下完");
                    this.txt_whiteState.setText("思考中");
                } else {
                    this.txt_whiteState.setText("已下完");
                    this.txt_blackState.setText("思考中");
                }
                // 判断游戏是否结束
                if (胜负判断()) {
                    this.isGameOver = true;
                    this.setComponentState(false);
                    this.txt_blackState.setText("已结束");
                    this.txt_whiteState.setText("已结束");
                    return;
                }
            }
        }
    }

    public void mousePressed(MouseEvent e) {
        System.out.println("鼠标点击又松开  mousePressed");
    }

    public void mouseReleased(MouseEvent e) {
        System.out.println("鼠标松开  mouseReleased");
    }

    public void mouseEntered(MouseEvent e) {
        System.out.println("鼠标进入  mouseEntered");
    }

    public void mouseExited(MouseEvent e) {
        System.out.println("鼠标离开  mouseExited");

    }

    public void mouseDragged(MouseEvent e) {
        System.out.println("鼠标按下以后拖动  mouseDragged");
    }

    public void mouseMoved(MouseEvent e) {
        //为了暂时能看到落子指示器,先把它写成false,等正式运行的时候再改
        if (this.isGameOver == true) {
            return;
        }

        //先让落子指示器不显示
        this.stepPointer.show = 0;

        int x = e.getX();
        int y = e.getY();

        //判断鼠标是不是在棋盘范围之内
        if (x > (Const.左上角坐标X - Const.格子宽度 / 2) && x < (Const.左上角坐标X + Const.棋盘宽度 + Const.格子宽度 / 2)
                && y > (Const.左上角坐标Y - Const.格子宽度 / 2) && y < (Const.左上角坐标Y + Const.棋盘高度 + Const.格子宽度 / 2)) {

            // 将x,y由像素改为相应的水平与垂直线的数目（0~19）
            int lineX = (x - Const.左上角坐标X + Const.格子宽度 / 2) / Const.格子宽度;
            int lineY = (y - Const.左上角坐标Y + Const.格子宽度 / 2) / Const.格子宽度;

            //判断该位置上是不是有棋子
            boolean hasChess = false;
            for (int i = 0; i < this.棋谱.size(); i++) {
                Step step = this.棋谱.get(i);
                if (step.x == lineX && step.y == lineY) {
                    hasChess = true;
                    break;
                }
            }

            if (hasChess == false) {
                this.stepPointer.x = lineX;
                this.stepPointer.y = lineY;
                this.stepPointer.show = 1;
            }
        } else {//鼠标不在棋盘内,清除落子指示器
            this.stepPointer.show = 0;
        }

        //手动引起 paint() 方法的调用
        this.repaint();
    }

    //判断这步棋应该是什么颜色
    public int getNextStepColor() {
        int color = -1;

        //如果棋谱中有信息,则根据棋谱最后一步,决定当前这步棋的颜色
        if (this.棋谱.size() > 0) {
            Step stepLast = this.棋谱.get(this.棋谱.size() - 1);
            if (stepLast.黑白标志 == Const.黑棋标识_1) {
                color = Const.白棋标识_2;
            } else {
                color = Const.黑棋标识_1;
            }
        }

        //如果棋谱中没信息,证明是第一次走棋
        else {
            // 人机对战
            if (this.fightType == 0) {
                // 玩家先手
                if (this.playFirst == 0) {
                    if (this.chessColor == 0) {
                        color = Const.黑棋标识_1;
                    } else {
                        color = Const.白棋标识_2;
                    }
                }
                // 电脑先手
                else {
                    if (this.chessColor == 0) {
                        color = Const.白棋标识_2;
                    } else {
                        color = Const.黑棋标识_1;
                    }
                }
            }

            // 人人对战
            else {
                if (this.chessColor == 0) {
                    color = Const.黑棋标识_1;
                } else {
                    color = Const.白棋标识_2;
                }
            }
        }
        return color;
    }


    boolean 胜负判断() {
        int hCount = 0; // 水平计数
        int vCount = 0; // 垂直计数
        int a45Count = 0; // 斜45度计数
        int a135Count = 0; // 斜135度计数
        boolean isFind = false; // 是否找到

        List<Step> hChessWin = new ArrayList<Step>(); // 记录水平方向上的5个点连成线
        List<Step> vChessWin = new ArrayList<Step>(); // 记录垂直方向上的5个点连成线
        List<Step> a45ChessWin = new ArrayList<Step>(); // 记录斜45度方向上的5个点连成线
        List<Step> a135ChessWin = new ArrayList<Step>(); // 记录斜135度方向上的5个点连成线

        // 得到最后一步下棋信息
        Step stepLast = this.棋谱.get(this.棋谱.size() - 1);
        int x = stepLast.x;
        int y = stepLast.y;
        int flag = stepLast.黑白标志;

        List<Step> listTmp;
        if (flag == Const.白棋标识_2) {
            listTmp = this.白谱;
        } else {
            listTmp = this.黑谱;
        }

        // 水平（先向右数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == (x + i) && step.y == y) {
                    hChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                hCount++;
            } else {
                break;
            }
        }

        // 水平（向左数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == (x - i) && step.y == y) {
                    hChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                hCount++;
            } else {
                break;
            }
        }

        // 垂直（向上数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == x && step.y == (y - i)) {
                    vChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                vCount++;
            } else {
                break;
            }
        }

        // 垂直（向下数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == x && step.y == (y + i)) {
                    vChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                vCount++;
            } else {
                break;
            }
        }

        // 45度斜线（向右上方数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == (x + i) && step.y == (y - i)) {
                    a45ChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                a45Count++;
            } else {
                break;
            }
        }
        // 45度斜线（向左下方数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == (x - i) && step.y == (y + i)) {
                    a45ChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                a45Count++;
            } else {
                break;
            }
        }

        // 135度斜线（向左上方数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == (x - i) && step.y == (y - i)) {
                    a135ChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                a135Count++;
            } else {
                break;
            }
        }
        // 135度斜线（向右下方数4个）
        for (int i = 1; i < 5; i++) {
            isFind = false;
            for (int j = 0; j < listTmp.size(); j++) {
                Step step = listTmp.get(j);
                if (step.x == (x + i) && step.y == (y + i)) {
                    a135ChessWin.add(step);
                    isFind = true;
                }
            }
            if (isFind) {
                a135Count++;
            } else {
                break;
            }
        }

        // 开始判断
        if (hCount >= 4 || vCount >= 4 || a45Count >= 4 || a135Count >= 4) {
            // 记录五子连线
            if (hChessWin.size() == 4) {
                hChessWin.add(stepLast);
                this.胜谱 = hChessWin;
            } else if (vChessWin.size() == 4) {
                vChessWin.add(stepLast);
                this.胜谱 = vChessWin;
            } else if (a45ChessWin.size() == 4) {
                a45ChessWin.add(stepLast);
                this.胜谱 = a45ChessWin;
            } else if (a135ChessWin.size() == 4) {
                a135ChessWin.add(stepLast);
                this.胜谱 = a135ChessWin;
            }

            // 人机对战
            if (this.fightType == 0) {
                if (flag == this.电脑棋子颜色) {
                    JOptionPane.showMessageDialog(null, "对不起,你输给了电脑！", "提示", JOptionPane.ERROR_MESSAGE);
                } else {
                    JOptionPane.showMessageDialog(null, "恭喜，你赢了电脑！");
                }
                return true;
            } else { // 人人对战
                if (flag == Const.白棋标识_2) {
                    JOptionPane.showMessageDialog(null, "恭喜，白棋赢了！");
                } else {
                    JOptionPane.showMessageDialog(null, "恭喜，黑棋赢了！");
                }
                return true;
            }
        }

        return false;

    }

}